import requests
import os
import time
import json

class MusicDownloader:
    def __init__(self):
        self.base_url = "https://ting.yeyulingfeng.com/"
        self.api_url = "https://ting.yeyulingfeng.com/yeyudata.php"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
            "Accept": "application/json, text/javascript, */*; q=0.01",
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
            "Referer": "https://ting.yeyulingfeng.com/",
            "X-Requested-With": "XMLHttpRequest"
        }
        self.sources = ["netease", "tencent", "kugou", "baidu"]
        
    def get_music_url(self, music_id, source):
        """获取音乐下载链接"""
        try:
            params = {
                "types": "url",
                "id": music_id,
                "source": source
            }
            
            response = requests.post(
                self.api_url,
                data=params,
                headers=self.headers,
                timeout=10
            )
            
            if response.status_code == 200:
                try:
                    data = response.json()
                    if data and "url" in data:
                        return data["url"]
                except:
                    print("解析音乐链接失败")
            return None
            
        except Exception as e:
            print(f"获取音乐链接出错: {str(e)}")
            return None
            
    def download_music(self, url, filename):
        """下载音乐文件"""
        try:
            response = requests.get(url, stream=True)
            total_size = int(response.headers.get('content-length', 0))
            
            if not os.path.exists("downloads/music"):
                os.makedirs("downloads/music")
                
            filepath = os.path.join("downloads/music", filename)
            
            with open(filepath, 'wb') as f:
                if total_size == 0:
                    f.write(response.content)
                else:
                    downloaded = 0
                    for data in response.iter_content(chunk_size=4096):
                        downloaded += len(data)
                        f.write(data)
                        done = int(50 * downloaded / total_size)
                        print(f"\r下载进度: [{'=' * done}{' ' * (50-done)}] {downloaded}/{total_size} 字节", end='')
            print(f"\n下载完成: {filepath}")
            return True
            
        except Exception as e:
            print(f"\n下载失败: {str(e)}")
            return False
    
    def search_music(self, keyword, source="netease"):
        try:
            print(f"\n正在搜索: {keyword} (音乐源: {source})")
            
            params = {
                "types": "search",
                "count": "20",
                "source": source,
                "name": keyword,
                "pages": "1"
            }
            
            response = requests.post(
                self.api_url,
                data=params,
                headers=self.headers,
                timeout=10
            )
            
            if response.status_code == 200:
                try:
                    data = response.json()
                    if data:
                        print("\n搜索结果:")
                        for idx, song in enumerate(data, 1):
                            print(f"\n{idx}. {song['name']} - {song['artist'][0]}")
                            print(f"   专辑: {song['album']}")
                            print(f"   来源: {song['source']}")
                            print(f"   ID: {song['id']}")
                        
                        # 选择要下载的歌曲
                        choice = input("\n请选择要下载的歌曲序号(输入 0 取消): ")
                        if choice.isdigit():
                            choice = int(choice)
                            if 0 < choice <= len(data):
                                song = data[choice-1]
                                print(f"\n获取下载链接: {song['name']}")
                                
                                url = self.get_music_url(song['id'], song['source'])
                                if url:
                                    filename = f"{song['name']} - {song['artist'][0]}.mp3"
                                    filename = filename.replace('/', '_').replace('\\', '_')
                                    self.download_music(url, filename)
                                else:
                                    print("获取下载链接失败")
                    else:
                        print(f"未找到结果，尝试其他音乐源...")
                        for alt_source in self.sources:
                            if alt_source != source:
                                self.search_music(keyword, alt_source)
                                break
                                
                except json.JSONDecodeError:
                    print("响应不是有效的 JSON 格式")
                    print("响应内容:")
                    print(response.text[:500])
            else:
                print(f"搜索请求失败: {response.status_code}")
                
        except requests.exceptions.RequestException as e:
            print(f"网络请求错误: {str(e)}")
        except Exception as e:
            print(f"处理出错: {str(e)}")
            import traceback
            print(traceback.format_exc())

def main():
    downloader = MusicDownloader()
    while True:
        keyword = input("\n请输入要搜索的音乐名称（输入 q 退出）: ").strip()
        if not keyword:
            print("请输入有效的关键词")
            continue
        if keyword.lower() == 'q':
            break
        downloader.search_music(keyword)
        time.sleep(1)

if __name__ == "__main__":
    print("音乐搜索器启动...")
    print("提示：输入音乐名称来搜索")
    main()